<template>
  <div class="table">
    <div v-if="searchConfig.dataList&&searchConfig.dataList.length>0" class="search-box">
      <div :class="[{'hide':!showMoreStatus}]" class="search-form-box">
        <mlform ref="searchForm" :config="searchConfig" v-model="searchInput" class="search-form"/>
        <div v-show="showMoreBtn" class="more" @click="showMoreStatus = !showMoreStatus">
          <i v-show="!showMoreStatus" class="el-icon-caret-bottom"/>
          <i v-show="showMoreStatus" class="el-icon-caret-top"/>
          展开更多
        </div>
      </div>
      <el-button class="reset" type="primary" size="small" plain @click="resetSearch"><i class="el-icon-refresh"/> 重置</el-button>
      <el-button class="search" type="primary" size="small" @click="search"><i class="el-icon-search"/> 搜索</el-button>
    </div>
    <div class="btn-box">
      <el-button
        v-for="(btn, index) in outerBtnGroup"
        :key="index"
        :type="btn.type || 'primary'"
        :disabled="(btn.selection==='single'&&(multipleSelection.length===0||multipleSelection.length>1))
        ||(btn.selection==='multiple'&&multipleSelection.length<1)"
        class="btn"
        size="small"
        @click="handleOuterBtn(btn.evtType, btn)">
        <i v-if="btn.Elicon" :class="['el-icon-'+btn.Elicon]"/>
        <svg-icon v-if="btn.icon" :icon-class="btn.icon" />
        {{ btn.name }}
      </el-button>
      <!-- <el-button size="small" @click="addShow">添加</el-button>
      <el-button size="small" @click="removeAll">删除</el-button> -->
    </div>
    <el-table
      v-loading="loading"
      :data="data"
      class="common-table"
      element-loading-text="拼命加载中"
      element-loading-spinner="el-icon-loading"
      element-loading-background="rgba(0, 0, 0, 0.8)"
      border
      stripe
      style="width: 100%"
      @sort-change="sortChange"
      @selection-change="handleSelectionChange">
      <!-- sortable 排序 -->
      <el-table-column type="selection" width="55"/>
      <el-table-column
        v-for="item in config.dataList"
        v-if="item.showTable || item.showTable === undefined"
        :prop="item.key"
        :key="item.key"
        :label="item.label"
        :sortable="item.sortable"
        :formatter="(row, column, cellValue, index)=>{
          return formatter(row, column, cellValue, index, item)
        }"
        align="center"
        show-overflow-tooltip/>
      <el-table-column fixed="right" label="操作" width="200" align="center">
        <template slot-scope="scope">
          <el-tooltip v-for="(btn, index) in innerBtnGroup" :key="index" :content="btn.name" effect="dark" placement="top">
            <el-button v-show="showJudgeInner(btn, scope.row)" :key="index" circle size="small" @click="handleInnerBtn(btn.evtType,scope.$index, scope.row)">
              <i v-if="btn.Elicon" :class="['el-icon-'+btn.Elicon]"/>
              <svg-icon v-if="btn.icon" :icon-class="btn.icon" />
            </el-button>
          </el-tooltip>
          <!-- <el-button icon="el-icon-more" circle size="small" @click="viewShow(scope.$index, scope.row)"/>
          <el-button icon="el-icon-edit" circle size="small" @click="editShow(scope.$index, scope.row)"/>
          <el-button icon="el-icon-delete" circle size="small" @click="deleteOne(scope.$index, scope.row)"/> -->
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      :current-page="currentPage"
      :page-sizes="[10, 20, 30]"
      :page-size="pageSize"
      :total="total"
      layout="total, sizes, prev, pager, next, jumper"
      class="table-pagination"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"/>
    <el-dialog
      :visible.sync="addVisible"
      :title="addTitle"
      width="1000px"
      @closed="closeAdd">
      <mlform ref="addForm" :config="addConfig" v-model="userInput"/>
      <span slot="footer" class="dialog-footer">
        <el-button size="small" @click="closeAdd">取 消</el-button>
        <el-button type="primary" size="small" @click="add">确 定</el-button>
      </span>
    </el-dialog>
    <el-dialog
      :visible.sync="editVisible"
      :title="editTitle"
      width="1000px">
      <mlform ref="editForm" :config="addConfig" v-model="userInput"/>
      <span slot="footer" class="dialog-footer">
        <el-button size="small" @click="closeEdit">取 消</el-button>
        <el-button type="primary" size="small" @click="edit">确 定</el-button>
      </span>
    </el-dialog>
    <el-dialog
      :visible.sync="viewVisible"
      :title="viewTitle"
      width="1000px">
      <viewForm ref="viewForm" :config="viewConfig" :value="userInput"/>
      <span slot="footer" class="dialog-footer">
        <el-button size="small" @click="closeView">取 消</el-button>
        <el-button type="primary" size="small" @click="closeView ">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
// TODO：按照表头排序，按钮显示，可用条件
// import component from "@/"
import mlform from '@/components/mlForm'
import viewForm from '@/components/mlViewForm'
import { copyObj } from '@/utils'
export default {
  name: 'Mltable',
  components: { mlform, viewForm },
  props: {
    config: {
      type: Object,
      required: true
    },
    formConfig: {
      type: Object,
      required: false,
      default() {
        return {
          inputWidth: '25%', // 表格搜索头宽度
          inline: true,
          labelWidth: '100px'
        }
      }
    },
    innerBtn: {
      type: Array,
      required: false,
      default() {
        return []
      }
    },
    outerBtn: {
      type: Array,
      required: false,
      default() {
        return []
      }
    },
    viewBtn: {
      type: Boolean,
      default: true
    },
    addBtn: {
      type: Boolean,
      default: true
    },
    deleteBtn: {
      type: Boolean,
      default: true
    },
    editBtn: {
      type: Boolean,
      default: true
    },
    addTitle: {
      type: null,
      default: '新增数据'
    },
    editTitle: {
      type: null,
      default: '修改数据'
    },
    viewTitle: {
      type: null,
      default: '查看详情'
    }
  },
  data() {
    return {
      addVisible: false,
      editVisible: false,
      viewVisible: false,
      userInput: {},
      searchInput: {},
      showMoreStatus: false,
      data: [],
      loading: false, // 加载遮罩
      pageSize: 10,
      currentPage: 1,
      total: 0,
      sort: '',
      sortType: '',
      multipleSelection: [], // 多选
      innerBtnGroup: this.innerBtn,
      outerBtnGroup: this.outerBtn
    }
  },

  computed: {
    searchConfig() {
      // 筛选表头搜索项，搜索类型转换，初始值
      const config = Object.assign(copyObj(this.config), this.formConfig)
      const dataList = config.dataList.filter(obj => obj.searchForm === undefined || obj.searchForm)
      const list = []
      dataList.forEach(obj => {
        const listObj = {}
        listObj.value = obj.tableSearchDefault || ''
        // if (obj.type === 'date' || obj.type === 'datetimerange' || obj.type === 'dateTime') {
        //   listObj.type = 'datetimerange'
        // } else if (obj.type === 'time' || obj.type === 'timerange') {
        //   listObj.type = 'timerange'
        // } else
        if (obj.type === 'select' || obj.type === 'radio' || obj.type === 'checkbox') {
          listObj.type = 'select'
          listObj.multiple = true
          listObj.options = [{ value: '', label: '所有' }, ...obj.options]
        } else if (obj.type === 'tree') {
          listObj.treeOptions = [{ value: '', label: '所有' }, ...obj.treeOptions]
        } else if (obj.type === 'color' || obj.type === 'date' || obj.type === 'datetimerange' || obj.type === 'dateTime' || obj.type === 'time' || obj.type === 'timerange') {
          listObj.type = obj.type
        } else {
          listObj.type = 'string'
        }

        listObj.label = obj.label
        listObj.key = obj.key

        list.push(listObj)
      })
      config.dataList = list
      console.log(config)
      return config
    },
    addConfig() {
      // 新增form配置
      const config = copyObj(this.config)
      config.dataList = config.dataList.filter(obj => obj.addForm === undefined || obj.addForm)
      console.log(config)
      return config
    },
    viewConfig() {
      // 查看详情form配置
      const config = copyObj(this.config)
      config.dataList = config.dataList.filter(obj => obj.viewForm === undefined || obj.viewForm)
      return config
    },
    showMoreBtn() {
      return parseInt(this.formConfig.inputWidth) / 100 * this.searchConfig.dataList.length > 1
    }
  },

  created() {
    this.data = []
    if (this.viewBtn) {
      this.innerBtnGroup.push({
        evtType: 'view',
        Elicon: 'view',
        name: '查看详情'
      })
    }
    if (this.addBtn) {
      this.outerBtnGroup.unshift({
        evtType: 'add',
        Elicon: 'plus',
        name: '新建'
        // selection: 'none' // false   不选,(其他值)， 单选，多选，single   multiple
        // icon: svg图标
        // showJudge : {name: 1 ,type: 2}
      })
    }
    if (this.deleteBtn) {
      this.outerBtnGroup.push({
        evtType: 'delete',
        Elicon: 'delete',
        name: '删除',
        type: 'danger',
        selection: 'multiple'
      })
      this.innerBtnGroup.push({
        evtType: 'delete',
        Elicon: 'delete',
        name: '删除'
      })
    }
    if (this.editBtn) {
      this.innerBtnGroup.push({
        evtType: 'edit',
        Elicon: 'edit',
        name: '编辑'
      })
    }
  },

  mounted() {
    this.search()
  },

  activated() {},

  methods: {
    // 表格内部按钮
    handleInnerBtn(type, index, row) {
      switch (type) {
        case 'view':
          this.viewShow(row)
          break
        case 'delete':
          this.delete([row])
          break
        case 'edit':
          this.editShow(row)
          break
        default:
          this.$emit(type, [row], index)
          break
      }
    },
    // 表格外按钮
    handleOuterBtn(type, btn) {
      if (btn.showJudge) {
        for (const key in btn.showJudge) {
          for (let i = 0; i < this.multipleSelection.length; i++) {
            if (this.multipleSelection[i][key] !== btn.showJudge[key]) {
              this.$message.warning('选择项不能进行该操作')
              return
            }
          }
        }
      }
      switch (type) {
        case 'add':
          this.addShow()
          break
        case 'delete':
          this.delete(this.multipleSelection)
          break
        default:
          this.$emit(type, this.multipleSelection)
          break
      }
    },
    // 按钮显示、可用判断
    showJudgeInner(btn, row) {
      if (btn.showJudge) {
        for (const key in btn.showJudge) {
          if (row[key] !== btn.showJudge[key]) {
            return false
          }
        }
      }
      return true
    },
    // 排序
    sortChange(obj) {
      // console.log(column, prop, order)
      this.sort = obj.prop
      this.sortType = { descending: 'DESC', ascending: 'ASC' }[obj.order] // ACS 顺序，从小到大， DESC倒序，从大到小
      this.search()
    },
    // 新增
    addShow() {
      this.$refs.addForm && this.$refs.addForm.clearValidate()
      this.addVisible = true
    },
    closeAdd() {
      this.userInput = {}
      this.addVisible = false
    },
    add() {
      if (this.$refs.addForm.validate()) {
        this.$http.post(this.config.api + '/add', this.userInput).then((res) => {
          this.search()
          this.closeAdd()
        }).catch((err) => {
          console.log(err)
          this.closeAdd()
        })
      }
    },

    // 删除
    delete(ary) {
      this.$confirm('此操作将永久删除数据, 是否继续?', '提示', {
        type: 'warning'
      }).then(() => {
        const ids = []
        ary.forEach(obj => {
          ids.push(obj[this.config.tableKey])
        })
        this.$http.post(this.config.api + '/delete', ids).then((res) => {
          this.search()
        }).catch((err) => {
          console.log(err)
          this.closeAdd()
        })
      })
    },
    removeAll() {
      this.multipleSelection.forEach(obj => {
        this.data.splice(this.data.findIndex(item => item[this.config.tableKey] === obj[this.config.tableKey]), 1)
      })
    },
    // 获取选择的项
    handleSelectionChange(val) {
      this.multipleSelection = val
    },
    // 修改
    editShow(row) {
      this.$refs.editForm && this.$refs.editForm.clearValidate()
      this.userInput = copyObj(row)
      this.editVisible = true
    },
    closeEdit() {
      this.userInput = {}
      this.editVisible = false
    },
    edit() {
      if (this.$refs.editForm.validate()) {
        this.$http.post(this.config.api + '/update', this.userInput).then((res) => {
          this.search()
          this.closeEdit()
        }).catch((err) => {
          console.log(err)
          this.closeAdd()
        })
      }
    },
    // 查询
    resetSearch() {
      this.$refs.searchForm.reset()
    },
    search() {
      if (this.$refs.searchForm) {
        if (!this.$refs.searchForm.validate()) {
          return
        }
      } else {
        setTimeout(() => {
          this.search()
        }, 500)
        return
      }
      this.loading = true
      const params = {
        condition: [{
          field: 'effective',
          val: true
        }],
        pager: {
          limit: this.pageSize,
          page: this.currentPage
        }
      }
      for (const key in this.searchInput) {
        if (this.searchInput[key]) {
          if (typeof this.searchInput[key] === 'object' && (JSON.stringify(this.searchInput[key]) === '[]' || JSON.stringify(this.searchInput[key]) === '[]')) {
            break
          }
          params.condition.push({
            field: key,
            val: this.searchInput[key]
          })
        }
      }
      if (this.sort && this.sortType) {
        params.pager.sort = this.sort
        params.pager.sortType = this.sortType
      }
      this.$http.post(this.config.api + '/list', params).then((res) => {
        this.data = res.data
        this.currentPage = res.page
        this.total = res.total
        this.loading = false
      }).catch((err) => {
        console.log(err)
        this.loading = false
      })
    },
    handleSizeChange(val) {
      this.pageSize = val
      this.search()
    },
    handleCurrentChange(val) {
      this.currentPage = val
      this.search()
    },
    // 查看
    viewShow(row) {
      this.$http.post(this.config.api + '/detail', row[this.config.tableKey]).then((res) => {
        this.userInput = res
        this.viewVisible = true
      }).catch((err) => {
        console.log(err)
      })
    },
    closeView() {
      this.viewVisible = false
    },
    // 递归得出树形得值
    treeVal(ary, val, index = 0, label = []) {
      console.log(ary, index, val, label)
      const obj = ary.find(obj => obj.value === val[index])
      label.push(obj.label)
      if (index < val.length - 1) {
        return this.treeVal(obj.children, val, index + 1, label)
      } else {
        return label.join('/')
      }
    },

    // 表单显示过滤，将单选，下拉的值转换为文字
    formatter(row, column, cellValue, index, config) {
      if (config.type === 'select' || config.type === 'radio' || config.type === 'checkbox') {
        if (!Array.isArray(cellValue)) {
          cellValue = [cellValue]
        }
        const val = []
        config.options.filter(obj => cellValue.filter(val => val === obj.value).length > 0).forEach(obj => {
          val.push(obj.label)
        })
        return val.join(',')
      } else if (config.type === 'tree') {
        return this.treeVal(config.treeOptions, cellValue)
      } else {
        return cellValue
      }
    }
  }
}
</script>

<style lang='scss' scoped>
.table{
  padding: 20px 8px;
  .search-box{
    @include inline(1);
    align-items: flex-end;
    padding-right: 20px;
    .search-form-box{
      &.hide{
        .search-form{
          height: 40px;
          overflow: hidden;
        }
        .more{
          margin: 5px auto 0;
        }
      }
      .more{
        width: 120px;
        font-size: 14px;
        height: 16px;
        margin: -20px auto 0;
        color: #d3dce6;
        cursor: pointer;
        &:hover{
          color: #409eff;
        }
      }
    }
    .search,.reset{
      margin-bottom: 26px;
      padding: 9px 20px;
    }
    .reset{
      margin-left: 30px;
    }
  }
  .table-pagination{
    text-align: right;
    margin-top: 10px;
  }
}
  .btn-box{
    padding: 10px 20px 10px;
    .btn{
      padding: 9px 30px;
    }
  }

</style>
<style lang="scss">
  .common-table thead th{
    color: #909399;
    font-weight: 500;
    background-color: #e7e7e7;
  }
</style>
